package top.lileix.mybatis.generator.x.domain.mapper;

import java.util.ArrayList;
import java.util.List;

import top.lileix.mybatis.generator.x.domain.Table;
import top.lileix.mybatis.generator.x.kit.MybatisXMLTool;

public class MapperXML {
    public ResultMap resultMap;
    public String domainPackagePath;
    public List<MyBatisSQL> sqls;
    static String deleteByPrimaryKeyFormat = "delete from %s where %s = #{%s,jdbcType=%s}";
    static String insertFormat = " insert into %s (%s) values (%s)";

    static String updateByPrimaryKeyFormat = "update %s  set %s where %s=#{%s,jdbcType=%s}";

    public MapperXML(Table t, String domainPackagePath) {
	resultMap = new ResultMap(t);
	this.domainPackagePath = domainPackagePath;
	sqls = new ArrayList<MyBatisSQL>();
	MyBatisSQL deleteByPrimaryKey = new MyBatisSQL("delete", "deleteByPrimaryKey", "String",
		"int", null);
	deleteByPrimaryKey.setText(String.format(deleteByPrimaryKeyFormat, t.getTableName(),
		resultMap.id.column, resultMap.id.property, resultMap.id.jdbcType));
	sqls.add(deleteByPrimaryKey);

	MyBatisSQL insert = new MyBatisSQL("insert", "insert", t.getModeName(), "int", null);
	insert.setText(String.format(insertFormat, t.getTableName(), getAllColumn(resultMap),
		getAllValues(resultMap)));
	sqls.add(insert);
	MyBatisSQL insertSelective = new MyBatisSQL("insert", "insertSelective", t.getModeName(),
		"int", null);
	insertSelective.setText(MybatisXMLTool.insert(t, resultMap));
	sqls.add(insertSelective);

	MyBatisSQL updateByPrimaryKey = new MyBatisSQL("update", "updateByPrimaryKey",
		t.getModeName(), "int", null);
	updateByPrimaryKey.setText(
		String.format(updateByPrimaryKeyFormat, t.getTableName(), getAllSetNotPK(resultMap),
			resultMap.id.column, resultMap.id.property, resultMap.id.jdbcType));
	sqls.add(updateByPrimaryKey);
	MyBatisSQL updateByPrimaryKeySelective = new MyBatisSQL("update",
		"updateByPrimaryKeySelective", t.getModeName(), "int", null);

	// XXX
	updateByPrimaryKeySelective.setText("--");
	sqls.add(updateByPrimaryKeySelective);

	MyBatisSQL selectByPrimaryKey = new MyBatisSQL("select", "selectByPrimaryKey", "String",
		t.getModeName(), "BaseResultMap");
	selectByPrimaryKey.setText("SELECT " + getAllColumn(resultMap) + " FROM " + t.getTableName()
		+ "WHERE " + resultMap.id.column + "=#{" + resultMap.id.property + ",jdbcType="
		+ resultMap.id.jdbcType + "}");
	sqls.add(selectByPrimaryKey);
	MyBatisSQL selectAll = new MyBatisSQL("select", "selectAll", null,
		"List<" + t.getModeName() + ">", "BaseResultMap");
	selectAll.setText("SELECT " + getAllColumn(resultMap) + " FROM " + t.getTableName());
	sqls.add(selectAll);

    }

    String getAllColumn(ResultMap resultMap) {
	StringBuilder sb = new StringBuilder(resultMap.id.column).append(",");
	for (Result r : resultMap.results) {
	    sb.append(r.column).append(",");
	}
	return sb.substring(0, sb.length() - 1);
    }

    String getAllValues(ResultMap resultMap) {
	StringBuilder sb = new StringBuilder("#{").append(resultMap.id.property)
		.append(",jdbcType=").append(resultMap.id.jdbcType).append("},");
	return sb.append(getAllValuesNotPK(resultMap)).toString();
    }

    String getAllValuesNotPK(ResultMap resultMap) {
	StringBuilder sb = new StringBuilder();
	for (Result r : resultMap.results) {
	    sb.append("#{").append(r.property).append(",jdbcType=").append(r.jdbcType).append("},");
	}
	return sb.substring(0, sb.length() - 1);
    }

    /**
     * create_time = #{createTime,jdbcType=TIMESTAMP},
     * 
     * @param resultMap
     * @return
     */
    String getAllSetNotPK(ResultMap resultMap) {
	StringBuilder sb = new StringBuilder();
	for (Result r : resultMap.results) {
	    sb.append(r.column).append("=");
	    sb.append("#{").append(r.property).append(",jdbcType=").append(r.jdbcType).append("},");
	}
	return sb.substring(0, sb.length() - 1);
    }
}
